Link to this headingSchnorr’s identification protocol
This is one of the most basic Protocols to prove that they know the Discrete logarithm secret.
Math Proof:
Y = g^X
B = g^A
Z = A + CX
\\~\\
\begin{aligned}
g^Z & = BY^C \\
& = g^A * (g^X)^C \\
\end{aligned}
Variations:
- Slim Version: Prover doesn’t send the shared_c and instead the verifier generates it.
- Subtract Version: Use
z = r - x*c and g^z * h^c = u rather than z = r + x*c and g^z = u * h^c
- Subtract & Derive: Use
z = r - x*c and g^z * h^c = u rather than z = r + x*c and g^z = u * h^c. Also only send shared_c and shared_z. shared_u is generated from u = g^z * h^c and then the hash is calculated with the generated shared_u and the prover_shared_c and the verifier_shared_c are compared.
Link to this headingMultiplicative Protocol
Interactive Protocol:
#Prover chooses the random secret x and generates the g^x -> h
#From DSA private key
=
#Prover then chooses another random secret r and generates the g^r -> u
= 0
=
=
return
#Check not zero or infinity point
assert != 0
assert != 0
#Check that output is in the group
assert > 0 and <
assert > 0 and <
#Generate a random c to send to prover
= 0
=
return
#Prover computes z = r + x * c. and sends to Verifier
return + *
#Verifier Checks that g^z = u* h^c
assert != 0
=
= %
assert ==
return True
## Setup
=
, , =
=
#First Step by Prover
, , =
#Send the shared_h, shared_u to the verifier
=
#Send the random_c to the prover
=
#Final Verication from the Verifier
Non-Interactive Protocol:
#Prover chooses the random secret x and generates the g^x -> h
#From DSA private key
=
#Prover then chooses another random secret r and generates the g^r -> u
= 0
=
=
#Use the Hash to generate the random c that is specific to the input varables
= + + + + + +
=
=
#Generate Random Z from z = r + x * c
= + *
return
#Check not zero or infinity point
assert != 0
assert != 0
#Check that output is in the group
assert > 0 and <
assert > 0 and <
#Check Z is not zero
assert != 0
#Have the Verifier compute the hash and dont trust the sent hash
= + + + + + +
=
=
#Verifier Checks that g^z = u * h^c
=
= %
assert ==
return True
## Setup
=
, , =
=
#First Step by Prover
, , , =
#Final Verication from the Verifier
Link to this headingAdditive Protocol
Interactive Protocol:
#Prover chooses the random secret x and generates the g*x -> h
#From DSA private key
= %
#Prover then chooses another random secret r and generates the g*r -> u
= 0
=
= %
return
#Check not zero or infinity point
assert != 0
assert != 0
#Check that output is in the group
assert > 0 and <
assert > 0 and <
#Generate a random c to send to prover
= 0
=
return
#Prover computes z = r + x * c. and sends to Verifier
return + *
#Verifier Checks that g*z = u* h^c
assert != 0
= %
= %
assert ==
return True
## Setup
=
, , =
=
#First Step by Prover
, , =
#Send the shared_h, shared_u to the verifier
=
#Send the random_c to the prover
=
#Final Verication from the Verifier
Non-Interactive Protocol:
#Prover chooses the random secret x and generates the g^x -> h
#From DSA private key
= %
#Prover then chooses another random secret r and generates the g^r -> u
= 0
=
= %
#Use the Hash to generate the random c that is specific to the input variables
= + + + + + +
=
=
#Generate Random Z from z = r + x * c
= + *
return
#Check not zero or infinity point
assert != 0
assert != 0
#Check that output is in the group
assert > 0 and <
assert > 0 and <
#Check Z is not zero
assert != 0
#Have the Verifier compute the hash and dont trust the sent hash
= + + + + + +
=
=
#Verifier Checks that g^z = u * h^c
= %
= %
assert ==
return True
## Setup
=
, , =
=
#First Step by Prover
, , , =
#Final Verication from the Verifier
Link to this headingPossible Security Issues
Input validation: Insure checks for valid transmitted values
Implicit Trust of Prover:
- Ensure generator_g and mod_q are valid known values
- recalculate and check the random_c from the hashed values
Missing Values:
- if shared_h or shared_u are missing its a major issue
- if generator_g or mod_q are missing it might be an issue
Weak Randomness:
- If there are two separate verifications with the same secret_r with different data this can leak the secret_x. https://www.zkdocs.com/docs/zkdocs/zero-knowledge-protocols/schnorr/
Replay Attacks: Ensure there is a ID to both the verifier and prover to prevent replay attacks
Link to this headingReused r attack
x = \dfrac{z_1 - z_2}{c_1 - c_2}
Link to this headingWeak Randomness Attack
If you use a weak random function you can prove that you know a secret key even though you dont.
#Lets take a random public Key that we dont know the private key for
=
#lets assume that the hash function uses the hash of the public key
=
#Lets use the random Z
=
=
Link to this headingReconstructing Public Key from Signatures